#ifndef CGLOBLE_H
#define CGLOBLE_H

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/prctl.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <opencv2/opencv.hpp>
#include <pthread.h>
#include <queue>
#include <semaphore.h>

using namespace std;
using namespace cv;

#include "comhead.h"

#define TEST_CHECKED    0x1
#define TEST_RUNING     0x2
#define TEST_FAIL       0x4
#define TEST_SUCESS     0x8

#define RE_SIZE_WIDTH 420
#define RE_SIZE_HEIGHT 240

#define GUI_PARA_CHANGE    0x1
#define FUNC_PARA_CHANGE     0x2

class Sem {
public:
    Sem(int init_value = 0)
    {
        sem_init(&mSem, 0, init_value);
    }

    bool Wait()
    {
        return sem_wait(&mSem) == 0;
    }

    bool Post()
    {
        return sem_post(&mSem) == 0;
    }

private:
    sem_t mSem;
};

class CMutex {
public:
    CMutex()
    {
        sem_init(&mSem, 0, 1); /** binary semaphore */
    }

    bool Lock()
    {
        return sem_wait(&mSem) == 0;
    }

    bool Unlock()
    {
        return sem_post(&mSem) == 0;
    }

private:

    sem_t mSem;
};

template <class T>

class CSingleton
{
public:
    CSingleton<T>()
    {
    }
    static T* GetInstance()
    {
        if(mInstance == 0)
        {
            mInstance = new T();
        }
        return mInstance;
    }
    static T* getInstance()
    {
        return GetInstance();
    }
private:
    static T* mInstance;
};

template <class T> T* CSingleton<T>::mInstance = 0;

class CGloble:public CSingleton<CGloble>
{
public:
    CGloble();
    void popQue(pair<SUdpDataHead,SUdpData>& item);
    bool pushQue(SUdpDataHead udp_head, SUdpData mat);
public:
    queue< pair<SUdpDataHead,SUdpData> > m_queWriteUdpData;
    Sem m_semUdp;
    CMutex m_mutexQue;
    pair<SUdpDataHead,SUdpData> m_pairWrite;

    bool m_bPushOK=false;
    int m_s32CurPoint = 0;
    int m_s32VPY = -1;

    int m_curTestIndx = 0;

    Sem m_execSem;
    bool m_bTestFinish = false;
private:
};

class SimpleThread
{
public:
    SimpleThread() : mShouldExit(false), mThr(0)
    {
    }

    virtual ~SimpleThread()
    {
        Stop();
    }

    virtual bool Start()
    {
        int ret = pthread_create(&mThr, NULL, thread, this);

        return ret == 0;
    }

    virtual void Stop()
    {
        void *retv;
        mShouldExit = true;
        if (mThr) {
            pthread_join(mThr, &retv);
            mThr = 0;
        }
    }

    virtual int Run() = 0;

    bool ShouldExit() const
    {
        return mShouldExit;
    }

    static void *thread(void *usr)
    {
        SimpleThread *t = static_cast<SimpleThread *>(usr);
        unsigned long r = t->Run();
        return (void *)r;
    }

protected:

    bool mShouldExit;
    pthread_t mThr;
};

#endif // CGLOBLE_H
